<?php
/**------------------------------------------------
 * |  Created By PhpStorm
 * |    Date: 21-4-26
 * |    Time: 上午9:18
 * |-----------------------------------------------
 * |  Author: yeyangyang <yeyangyang@qq.com>
 * '----------------------------------------------*/

namespace app\common\middleware;

use think\facade\Config;

/**
 * Class Sign
 * @package app\common\middleware
 */
class Sign
{
    /**
     * 处理请求
     *
     * @param Request $request
     * @param Closure $next
     *
     * ------------------- eg:start ---------------------
     * 1. 获取POST请求参数和请求头:access-sign/access-time/access-version
     * 2. 对关联数组按照键名进行升序排序
     * 3. 生成以&符链接的key=value形式的字符串,最后在加上 key 值
     * 4. 对链接值进行md5加密,在转换成大写
     * ------------------- eg:end -----------------------
     *
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $overTime   = Config::get('meadmin.sign_time');
        $data       = [];

        // 获取请求头
        $accessDebug        = $request->header('access-debug');
        $accessSign         = $request->header('access-sign');
        $accessTime         = $data['timestamp']  = $request->header('access-time');
        $accessVersion      = $data['version']    = $request->header('access-version');
        // 验证请求头不能为空
        if (empty($accessSign) || empty($accessTime) || empty($accessVersion)) {
            return error(Config::get('error_code.4201.code'),Config::get('error_code.4201.msg'));
        }

        // 获取请求参数
        $query  = $request->post();
        $data   = array_merge($query,$data);
        $sign = $this->_generateSign($data);

        // 验证是否是debug模式
        if($accessDebug=='debug'){
            // 返回签名
            return success(200,'操作成功',$sign);
        }
        // 验证签名是否过期
        if ($accessTime+$overTime < time()) {
            // 超时
            return error(Config::get('error_code.4202.code'),Config::get('error_code.4202.msg'));
        }
        // 验证签名
        if(strtoupper($accessSign)!=$sign){
            // 签名错误
            return error(Config::get('error_code.4203.code'),Config::get('error_code.4203.msg'));
        }

        return $next($request);
    }


    // 生成签名
    private function _generateSign($data)
    {
        $key = Config::get('meadmin.sign_key');

        //获取签名
        ksort($data);
        $paramString = http_build_query($data)."&key={$key}";
        $sign = strtoupper(MD5($paramString));

        return $sign;
    }



}
